package org.csu.jpetstore.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.csu.jpetstore.bo.LineItemBO;
import org.csu.jpetstore.bo.OrderBO;
import org.csu.jpetstore.entity.LineItem;
import org.csu.jpetstore.entity.Order;
import org.csu.jpetstore.entity.OrderStatus;
import org.csu.jpetstore.mapper.LineItemMapper;
import org.csu.jpetstore.mapper.OrderMapper;
import org.csu.jpetstore.mapper.OrderStatusMapper;
import org.csu.jpetstore.service.CartService;
import org.csu.jpetstore.service.ItemService;
import org.csu.jpetstore.service.OrderService;
import org.csu.jpetstore.service.SequenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author huangzhangyan
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private LineItemMapper lineItemMapper;
    @Autowired
    private OrderStatusMapper orderStatusMapper;
    @Autowired
    private SequenceService sequenceService;
    @Autowired
    private CartService cartService;
    @Autowired
    private ItemService itemService;

    /**
     * 通过username获取该用户订单列表
     *
     * @param username 用户名
     * @return List<OrderBO>
     * @author huangzhangyan
     * @date 2022/4/13 19:42
     */
    @Override
    public List<OrderBO> getOrderBOListByUsername(String username) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", username);
        List<Order> orderList = orderMapper.selectList(queryWrapper);
        List<OrderBO> orderBOList = new ArrayList<>();
        for (Order order : orderList) {
            orderBOList.add(OrderBO.toOrderBO(order, this.getLineItemBOListByOrderId(order.getOrderId())));
        }
        return orderBOList;
    }

    /**
     * 通过订单号获取订单
     *
     * @param orderId 订单号
     * @return OrderBO
     * @author huangzhangyan
     * @date 2022/4/13 19:50
     */
    @Override
    public OrderBO getOrderBOById(int orderId) {
        Order order = orderMapper.selectById(orderId);
        return OrderBO.toOrderBO(order, this.getLineItemBOListByOrderId(order.getOrderId()));
    }

    /**
     * 插入订单
     * <p>
     * 插入新的Order需要:
     * 通过sequence获取orderId,
     * 插入order表一条数据,
     * 插入line_item表多条数据,
     * 插入order_status表多条数据
     * 最后删除用户购物车
     * <p>
     * 如果是提交订单 对应商品数量减少
     * <p>
     * 其中多条数据的数量由订单中包含的Item种类的数目决定
     * <p>
     * 其中line_item和order_status表通过字段order_id和line_number(两个表中都有)联系,
     * 本质上这两个字段构成复合主键,为了Mybatis使用方便,各自设置了自增长的无实际意义的Id作为其主键
     *
     * @param orderBO 订单
     * @author huangzhangyan
     * @date 2022/4/13 19:54
     */
    @Override
    public void insertOrder(OrderBO orderBO) {
        Integer orderId = sequenceService.getNextIdByName("order_number").getNextId();
        orderBO.setOrderId(orderId);
        for (LineItemBO lineItemBO : orderBO.getLineItemBOList()) {
            lineItemBO.setOrderId(orderId);
        }
        orderMapper.insert(OrderBO.toOrderEntity(orderBO));

        for (LineItemBO lineItemBO : orderBO.getLineItemBOList()) {
            lineItemMapper.insert(LineItemBO.toLineItem(lineItemBO));
            //提交订单后对应商品的数量相应减少
            itemService.updateInventoryQuantity(lineItemBO.getItemId(), lineItemBO.getQuantity());
        }

        for (LineItemBO lineItemBO : orderBO.getLineItemBOList()) {
            orderStatusMapper.insert(LineItemBO.toOrderStatus(lineItemBO));
        }


        //删除用户购物车
        cartService.clearCartByUsername(orderBO.getUserId());
    }

    /**
     * 更新订单状态为 已付
     *
     * @param orderId 订单号
     * @description 付完款修改订单的状态
     * @author CSU_Luoyuhang
     * @date 2022/4/13 15:21
     */
    @Override
    public void updateOrder(String orderId) {
        UpdateWrapper<OrderStatus> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_id", orderId).set("status", "已付");
        orderStatusMapper.update(null, updateWrapper);

    }

    /**
     * 弃用的
     */
    @Deprecated
    public List<LineItem> getLineItemListByOrderId(int orderId) {
        QueryWrapper<LineItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId);
        return lineItemMapper.selectList(queryWrapper);
    }

    /**
     * 根据订单号获取 LineItemBO
     *
     * @param orderId 订单号
     * @return List<LineItemBO>
     * @author huangzhangyan
     * @date 2022/4/15 20:55
     */
    @Override
    public List<LineItemBO> getLineItemBOListByOrderId(int orderId) {
        QueryWrapper<LineItem> lineItemWrapper = new QueryWrapper<>();
        lineItemWrapper.eq("order_id", orderId);
        QueryWrapper<OrderStatus> orderStatusWrapper = new QueryWrapper<>();
        orderStatusWrapper.eq("order_id", orderId);
        List<LineItem> lineItemList = lineItemMapper.selectList(lineItemWrapper);
        List<OrderStatus> orderStatusList = orderStatusMapper.selectList(orderStatusWrapper);
        if (lineItemList.size() != orderStatusList.size()) {
            throw new RuntimeException();
        }
        List<LineItemBO> lineItemBOList = new ArrayList<>();
        for (int i = 0; i < lineItemList.size(); i++) {
            lineItemBOList.add(LineItemBO.toLineItemBO(lineItemList.get(i), orderStatusList.get(i)));
        }
        return lineItemBOList;
    }
}
